 ; void lista_insertar_ordenado( nodo_lista_t **l, nodo_lista_t *n)

%include "macros.mac"

%define ptr_ptr_l	[ebp+8]
%define ptr_n		[ebp+12]
%define offset_l_nodo_arbol	0
%define offset_l_sig		4
%define offset_a_apariciones	1

global lista_insertar_ordenado

section .text

lista_insertar_ordenado:
	convencion_C 0
	push ecx
	push edx

	; Guardo *l en ebx
	mov ebx, dword ptr_ptr_l	; ebx tiene l
	mov ecx, [ebx]
	
	;Si la lista es vacia, cambio el puntero al primero, a n
	cmp ecx, dword 0		; ¿ *l == NULL ?
	jne .casolistaNoVacia
	
	; CASO LISTA VACIA
	mov edi, dword ptr_ptr_l	; edi tiene l
	mov esi, dword ptr_n		; esi tiene n
	mov [edi], esi				; Hace *l = n

	jmp .fin

.casolistaNoVacia:

	; Guardo en ecx la cantidad de apariciones de n
	mov ecx, dword ptr_n				; ecx = n
	mov ecx, dword [ecx + offset_l_nodo_arbol]	; ecx = n->nodo_arbol
	mov ecx, dword [ecx + offset_a_apariciones] ; ecx = (n->nodo_arbol)->apariciones
	
	; Guardo en edx la cantidad de apariciones del nodo actual
	mov edx, ebx					; edx = l
	mov edx, dword [edx]				; edx = *l = nodo_actual
	mov edx, dword [edx + offset_l_nodo_arbol]	; edx = nodo_actual->nodo_arbol
	mov edx, dword [edx + offset_a_apariciones]	; edx = (nodo_actual->nodo_arbol)->apariciones
	
	; (Abuso del lenguaje...)
	; Si apariciones de n < apariciones de nodo_actual, no salto
	cmp ecx, edx
	jnb .casoTieneAnterior

		; --MENOR QUE EL PRIMER NODO
		; Inserto al principio de la lista el nodo n
		;      esi ---> puntero a n
		;      ebx ---> puntero al primero de la lista
		; el siguiente de n es el nodo que ya estaba
		
		mov ecx, [ebx]						; ecx = *l
		mov esi, ptr_n						; esi = n
		mov [esi + offset_l_sig], ecx				; n->sig = *l

		; cambio el puntero al primero de la lista
		mov edi, dword ptr_ptr_l					; edi tiene ahora a l
		mov [edi], esi								; *l = n
	
		jmp .fin

; ebx ---> l
; ecx ---> apariciones de n
; edx ---> apariciones de actual
.casoTieneAnterior:
	; esi --->ptr a nodo actual
	; edi --->ptr a nodo siguiente		
	mov esi, [ebx]				; esi = *l			puntero al primero de la lista
	mov edi, dword [esi + offset_l_sig]	; edi = *l->sig		puntero al segundo de la lista
	
	mov ebx, dword ptr_n			; Ahora ebx -----> n
	
.ciclo:
	; Si llego al final, lo inserto despues del nodo actual
	cmp edi, 0
	je .insertar
	
	; Si no
	; Guardo en edx la cantidad de apariciones del nodo siguiente
	mov edx, dword [edi + offset_l_nodo_arbol]		; edx = siguiente->nodo_arbol
	mov edx, dword [edx + offset_a_apariciones] 	; edx = (siguiente->nodo_arbol)->apariciones

	; Si apariciones de n >= apariciones de actual, avanzo y vuelvo al ciclo
	cmp ecx, edx
	jnae .insertar

.avanzar:
	mov esi, edi						; actual = siguiente
	mov edi, [edi + offset_l_sig]		; siguiente = siguiente->sig
	jmp .ciclo

.insertar:
	mov [esi + offset_l_sig], ebx		; actual->sig = n
	mov [ebx + offset_l_sig], edi		; n->sig tiene el puntero al siguiente de actual, antes de la asignacion
.fin:
	pop edx
	pop ecx
	convencion_C_fin 0
	ret
